package mianshi;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class CodeCounter {

	static int threadCount = 5;// max count
	static Integer currentThreadCount = 0;// current count
	static Long whiteLines = 0L;
	static Long commentLines = 0L;
	static Long normalLines = 0L;
	static Long totalLines = 0L;
	static Integer fileCount = 0;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		File f = new File("D:\\Work\\workspace\\test\\src\\mianshi");// folder
		File[] codeFiles = f.listFiles();
		fileCount = codeFiles.length;
		for (File child : codeFiles) {
			if (child.getName().matches(".*\\.java$")) {
				parse(child);
			}
		}
		while (true) {
			if (fileCount == 0) {
				System.out.println("SumWhiteLines:" + whiteLines);
				System.out.println("SumCommentLines:" + commentLines);
				System.out.println("SumNormalLines:" + normalLines);
				System.out.println("SumTotalLines:" + totalLines);
				break;
			}
		}
	}

	private static void parse(final File file) {
		while (true) {
			synchronized (currentThreadCount) {
				if (currentThreadCount < threadCount) {
					currentThreadCount++;
				}
			}
			break;
		}
		startParseThread(file);
	}

	private static void startParseThread(final File file) {
		new Thread() {
			public void run() {
				parseFile(file);
				synchronized (currentThreadCount) {
					currentThreadCount--;
				}
				synchronized (fileCount) {
					fileCount--;
				}
			}

			private void parseFile(File file) {
				BufferedReader br = null;
				boolean comment = false;
				try {
					br = new BufferedReader(new FileReader(file));
					String line = "";
					long currWhiteLines = 0;
					long currCommentLines = 0;
					long currNormalLines = 0;
					long currTotalLines = 0;
					while ((line = br.readLine()) != null) {
						currTotalLines++;
						line = line.trim();
						if (line.matches("^[\\s&&[^\\n]]*$")) {
							currWhiteLines++;
						} else if (line.startsWith("/*")
								&& !line.endsWith("*/")) {
							currCommentLines++;
							comment = true;
						} else if (line.startsWith("/*") && line.endsWith("*/")) {
							currCommentLines++;
						} else if (true == comment) {
							currCommentLines++;
							if (line.endsWith("*/")) {
								comment = false;
							}
						} else if (line.startsWith("//")) {
							currCommentLines++;
						} else {
							currNormalLines++;
						}
					}
					synchronized (whiteLines) {
						whiteLines += currWhiteLines;
					}
					synchronized (commentLines) {
						commentLines += currCommentLines;
					}
					synchronized (normalLines) {
						normalLines += currNormalLines;
					}
					synchronized (totalLines) {
						totalLines += currTotalLines;
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					if (br != null) {
						try {
							br.close();
							br = null;
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}.start();
	}

}
